<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>代码查看器 - 静态演示</title>
    <!-- Prism.js CSS -->
    <link href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism.min.css" rel="stylesheet">
    <!-- 自定义样式 -->
    <style>
        /* 基础样式 */
        * {
            box-sizing: border-box;
        }

        body {
            margin: 0;
            padding: 0;
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;
            background-color: #ffffff;
            color: #333;
            line-height: 1.6;
        }

        .code-viewer-container {
            display: flex;
            flex-direction: column;
            height: 100vh;
            background-color: #ffffff;
        }

        /* 头部信息栏 */
        .header-bar {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 16px 24px;
            background: #f8f9fa;
            border-bottom: 1px solid #e9ecef;
            flex-shrink: 0;
        }

        .file-info {
            display: flex;
            flex-direction: column;
            gap: 4px;
        }

        .file-title {
            margin: 0;
            font-size: 20px;
            font-weight: 600;
            color: #333;
        }

        .file-details {
            font-size: 14px;
            color: #666;
        }

        .syntax-support {
            font-size: 12px;
            color: #28a745;
            font-weight: 500;
        }

        .actions {
            display: flex;
            gap: 12px;
        }

        .btn {
            display: inline-block;
            padding: 8px 16px;
            background: #007acc;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
            transition: background-color 0.2s;
            text-decoration: none;
        }

        .btn:hover {
            background: #005a9e;
        }

        .btn-secondary {
            background: #f5f5f5;
            color: #333;
        }

        .btn-secondary:hover {
            background: #e8e8e8;
        }

        /* 主内容区域 */
        .main-content {
            display: flex;
            flex: 1;
            overflow: hidden;
        }

        /* 区域信息面板 */
        .regions-panel {
            width: 260px;
            background: #f8f9fa;
            border-right: 1px solid #e9ecef;
            padding: 20px;
            overflow-y: auto;
            flex-shrink: 0;
        }

        .regions-panel h3 {
            margin: 0 0 16px 0;
            font-size: 16px;
            font-weight: 600;
            color: #333;
        }

        .regions-panel h4 {
            margin: 20px 0 12px 0;
            font-size: 14px;
            font-weight: 600;
            color: #333;
        }

        .regions-list {
            display: flex;
            flex-direction: column;
            gap: 12px;
            margin-bottom: 24px;
        }

        .region-item {
            background: #ffffff;
            border: 1px solid #e9ecef;
            border-radius: 6px;
            padding: 12px;
            transition: all 0.2s ease;
        }

        .region-item:hover {
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
            border-color: #007acc;
        }

        .region-info {
            display: flex;
            flex-direction: column;
            gap: 4px;
            margin-bottom: 8px;
        }

        .region-name {
            font-weight: 500;
            color: #333;
            font-size: 14px;
        }

        .region-lines {
            font-size: 12px;
            color: #666;
        }

        .region-status {
            display: flex;
            justify-content: flex-end;
        }

        .status-badge {
            background: #d4edda;
            color: #155724;
            padding: 2px 8px;
            border-radius: 12px;
            font-size: 11px;
            font-weight: 500;
            border: 1px solid rgba(0, 0, 0, 0.1);
        }

        .quick-actions {
            border-top: 1px solid #e9ecef;
            padding-top: 16px;
            margin-bottom: 20px;
        }

        .btn-action {
            display: block;
            width: 100%;
            padding: 8px 12px;
            margin-bottom: 8px;
            background: #ffffff;
            border: 1px solid #007acc;
            color: #007acc;
            border-radius: 4px;
            cursor: pointer;
            font-size: 13px;
            font-weight: 500;
            transition: all 0.2s;
        }

        .btn-action:hover {
            background: #007acc;
            color: white;
        }

        /* 语法高亮信息面板 */
        .syntax-info {
            border-top: 1px solid #e9ecef;
            padding-top: 16px;
        }

        .syntax-status {
            display: flex;
            flex-direction: column;
            gap: 8px;
        }

        .language-tag {
            display: inline-block;
            background: #007acc;
            color: white;
            padding: 2px 8px;
            border-radius: 12px;
            font-size: 11px;
            font-weight: 600;
            text-align: center;
        }

        .support-status.supported {
            color: #28a745;
            font-size: 12px;
            font-weight: 500;
        }

        /* 编辑器容器 */
        .editor-container {
            display: flex;
            flex-direction: column;
            flex: 1;
            overflow: hidden;
        }

        .editor-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 12px 16px;
            background: #f1f3f4;
            border-bottom: 1px solid #e9ecef;
            flex-shrink: 0;
        }

        .editor-title {
            font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
            font-size: 14px;
            font-weight: 500;
            color: #333;
        }

        .editor-language {
            font-size: 12px;
            color: #666;
            background: #e9ecef;
            padding: 2px 8px;
            border-radius: 12px;
        }

        /* 代码显示区域 */
        .code-display-container {
            flex: 1;
            overflow-y: auto;
            background: #ffffff;
            font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', monospace;
            font-size: 14px;
            line-height: 1.5;
        }

        .line-container {
            display: flex;
            align-items: flex-start;
            min-height: 21px;
            border-left: 3px solid transparent;
        }

        .line-container:hover .code-line:not(.original-visible) {
            background-color: #f8f9fa;
        }

        .line-container:hover .code-line.original-visible {
            filter: brightness(0.95);
        }

        .code-line {
            display: flex;
            width: 100%;
            align-items: flex-start;
            transition: all 0.2s ease;
        }

        .line-number {
            flex-shrink: 0;
            width: 60px;
            padding: 0 16px 0 12px;
            color: #666;
            text-align: right;
            font-size: 12px;
            border-right: 1px solid #e9ecef;
            line-height: 21px;
            background: inherit;
        }

        .line-content {
            flex: 1;
            margin: 0;
            padding: 0 16px;
            white-space: pre;
            word-wrap: break-word;
            overflow-x: auto;
            font-family: inherit;
            font-size: inherit;
            line-height: inherit;
            color: #333;
            background: inherit;
        }

        /* 原始可见区域样式 */
        .code-line.original-visible {
            position: relative;
        }

        .code-line.original-visible::before {
            content: '';
            position: absolute;
            left: 0;
            top: 0;
            bottom: 0;
            width: 3px;
            background: linear-gradient(180deg, #007acc, #0056b3);
        }

        .code-line.original-visible .line-number {
            background: rgba(255, 255, 255, 0.8);
            backdrop-filter: blur(1px);
        }

        /* 手动展开区域样式 */
        .code-line.manually-expanded {
            background: transparent !important;
            position: relative;
        }

        .code-line.manually-expanded::before {
            content: '';
            position: absolute;
            left: 0;
            top: 0;
            bottom: 0;
            width: 3px;
            background: #dee2e6;
        }

        .code-line.manually-expanded .line-number {
            background: #f8f9fa;
            color: #888;
        }

        .code-line.manually-expanded .line-content {
            color: #555;
        }

        .code-line.manually-expanded .token {
            opacity: 0.8;
        }

        /* 折叠占位符行 */
        .collapsed-line {
            display: flex;
            width: 100%;
            background: #f8f9fa;
            border: 1px solid #e9ecef;
            border-left: 3px solid #007acc;
            margin: 2px 0;
        }

        .line-number-range {
            flex-shrink: 0;
            width: 60px;
            padding: 8px 16px 8px 12px;
            color: #666;
            text-align: right;
            font-size: 11px;
            background: #e9ecef;
            border-right: 1px solid #dee2e6;
            font-weight: 500;
        }

        .collapsed-content {
            flex: 1;
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 8px 16px;
        }

        .collapsed-text {
            color: #666;
            font-style: italic;
            font-size: 13px;
        }

        .expand-actions {
            flex-shrink: 0;
            margin-left: 16px;
        }

        .expand-btn {
            display: flex;
            align-items: center;
            gap: 6px;
            padding: 4px 12px;
            background: #007acc;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 12px;
            font-weight: 500;
            transition: all 0.2s;
        }

        .expand-btn:hover {
            background: #005a9e;
            transform: translateY(-1px);
            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
        }

        .expand-icon {
            font-size: 10px;
            transition: transform 0.2s;
        }

        .expand-btn:hover .expand-icon {
            transform: scale(1.1);
        }

        /* 使用说明 */
        .help-panel {
            background: #f8f9fa;
            border-top: 1px solid #e9ecef;
            padding: 16px 24px;
            flex-shrink: 0;
        }

        .help-panel details summary {
            cursor: pointer;
            font-weight: 500;
            color: #666;
            font-size: 14px;
        }

        .help-panel details summary:hover {
            color: #333;
        }

        .help-content {
            margin-top: 12px;
        }

        .help-content ul {
            margin: 0;
            padding-left: 20px;
        }

        .help-content li {
            font-size: 14px;
            color: #666;
            line-height: 1.5;
            margin-bottom: 4px;
        }

        .help-content strong {
            color: #333;
        }

        /* 自定义语法高亮样式 */
        .token.comment,
        .token.prolog,
        .token.doctype,
        .token.cdata {
            color: #6a9955;
            font-style: italic;
        }

        .token.keyword {
            color: #0000ff;
        }

        .token.string,
        .token.attr-value {
            color: #a31515;
        }

        .token.number {
            color: #098658;
        }

        .token.function {
            color: #795e26;
        }

        .token.class-name {
            color: #267f99;
        }

        .token.operator,
        .token.punctuation {
            color: #000000;
        }

        .token.property,
        .token.constant,
        .token.symbol {
            color: #005cc5;
        }

        /* 响应式设计 */
        @media (max-width: 768px) {
            .main-content {
                flex-direction: column;
            }

            .regions-panel {
                width: 100%;
                max-height: 250px;
                border-right: none;
                border-bottom: 1px solid #e9ecef;
            }

            .btn-action {
                display: inline-block;
                width: auto;
                margin-right: 8px;
                margin-bottom: 8px;
            }

            .syntax-status {
                flex-direction: row;
                align-items: center;
                gap: 12px;
            }

            .header-bar {
                flex-direction: column;
                gap: 12px;
                align-items: stretch;
            }

            .file-info {
                text-align: center;
            }

            .code-line .line-number {
                width: 40px;
                padding: 0 8px 0 8px;
                font-size: 11px;
            }

            .code-line .line-content {
                padding: 0 12px;
                font-size: 13px;
            }

            .collapsed-line .line-number-range {
                width: 40px;
                padding: 6px 8px;
                font-size: 10px;
            }

            .collapsed-content {
                padding: 6px 12px;
            }

            .collapsed-text {
                font-size: 12px;
            }

            .expand-actions {
                margin-left: 8px;
            }

            .expand-btn {
                padding: 3px 8px;
                font-size: 11px;
            }
        }
    </style>
</head>
<body>
    <div class="code-viewer-container">
        <!-- 头部信息栏 -->
        <div class="header-bar">
            <div class="file-info">
                <h2 class="file-title">代码查看器 - 静态演示</h2>
                <span class="file-details">example.component.ts (72 行)</span>
                <span class="syntax-support">✨ 语法高亮支持 (TypeScript)</span>
            </div>
            <div class="actions">
                <button class="btn btn-secondary" onclick="reloadData()">重新加载</button>
            </div>
        </div>

        <!-- 主内容区域 -->
        <div class="main-content">
            <!-- 区域信息面板 -->
            <div class="regions-panel">
                <h3>显示区域</h3>
                <div class="regions-list">
                    <div class="region-item">
                        <div class="region-info">
                            <span class="region-name">区域 1</span>
                            <span class="region-lines">第 1 - 8 行</span>
                        </div>
                        <div class="region-status">
                            <span class="status-badge" style="background-color: #e3f2fd; color: #333;">已显示</span>
                        </div>
                    </div>
                    <div class="region-item">
                        <div class="region-info">
                            <span class="region-name">区域 2</span>
                            <span class="region-lines">第 14 - 23 行</span>
                        </div>
                        <div class="region-status">
                            <span class="status-badge" style="background-color: #f3e5f5; color: #333;">已显示</span>
                        </div>
                    </div>
                    <div class="region-item">
                        <div class="region-info">
                            <span class="region-name">区域 3</span>
                            <span class="region-lines">第 35 - 42 行</span>
                        </div>
                        <div class="region-status">
                            <span class="status-badge" style="background-color: #e8f5e8; color: #333;">已显示</span>
                        </div>
                    </div>
                    <div class="region-item">
                        <div class="region-info">
                            <span class="region-name">区域 4</span>
                            <span class="region-lines">第 55 - 67 行</span>
                        </div>
                        <div class="region-status">
                            <span class="status-badge" style="background-color: #fff3e0; color: #333;">已显示</span>
                        </div>
                    </div>
                </div>
                
                <!-- 快速操作 -->
                <div class="quick-actions">
                    <h4>快速操作</h4>
                    <button class="btn-action" onclick="expandAll()">展开所有隐藏行</button>
                    <button class="btn-action" onclick="collapseAll()">重置显示</button>
                </div>

                <!-- 语法高亮信息 -->
                <div class="syntax-info">
                    <h4>语法高亮</h4>
                    <div class="syntax-status">
                        <span class="language-tag">TYPESCRIPT</span>
                        <span class="support-status supported">✓ 已启用</span>
                    </div>
                </div>
            </div>

            <!-- 编辑器容器 -->
            <div class="editor-container">
                <div class="editor-header">
                    <span class="editor-title">example.component.ts</span>
                    <span class="editor-language">typescript</span>
                </div>
                
                <!-- 代码显示区域 -->
                <div id="code-display" class="code-display-container">
                    <!-- 动态生成的代码行将在这里显示 -->
                </div>
            </div>
        </div>

        <!-- 使用说明 -->
        <div class="help-panel">
            <details>
                <summary>使用说明</summary>
                <div class="help-content">
                    <ul>
                        <li>页面显示代码文件的指定区域，<strong>带颜色背景的是原始显示区域</strong></li>
                        <li>代码支持<strong>语法高亮</strong>，关键字、字符串、注释等会以不同颜色显示</li>
                        <li>点击折叠行中的"展开"按钮来查看隐藏的代码（无背景色）</li>
                        <li>左侧面板显示当前可见区域的信息，颜色标签表示该区域背景色</li>
                        <li>使用快速操作可以一键展开所有隐藏行或重置显示</li>
                    </ul>
                </div>
            </details>
        </div>
    </div>

    <!-- Prism.js JavaScript -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-core.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>

    <script>
        // Mock 代码行数据，包含背景色信息
        const regionBackgrounds = {
            'region1': '#e3f2fd',
            'region2': '#f3e5f5', 
            'region3': '#e8f5e8',
            'region4': '#fff3e0'
        };

        const mockCodeLines = [
            { lineNumber: 1, content: "import { Component, OnInit } from '@angular/core';", lineType: 'original', regionId: 'region1' },
            { lineNumber: 2, content: "import { CommonModule } from '@angular/common';", lineType: 'original', regionId: 'region1' },
            { lineNumber: 3, content: "import { FormsModule } from '@angular/forms';", lineType: 'original', regionId: 'region1' },
            { lineNumber: 4, content: "import { HttpClient } from '@angular/common/http';", lineType: 'original', regionId: 'region1' },
            { lineNumber: 5, content: "import { Observable } from 'rxjs';", lineType: 'original', regionId: 'region1' },
            { lineNumber: 6, content: "", lineType: 'original', regionId: 'region1' },
            { lineNumber: 7, content: "// 用户数据接口", lineType: 'original', regionId: 'region1' },
            { lineNumber: 8, content: "interface UserData {", lineType: 'original', regionId: 'region1' },
            { isCollapsed: true, hiddenStart: 9, hiddenEnd: 13, content: "// ··· 5 行被折叠 ···" },
            { lineNumber: 14, content: "@Component({", lineType: 'original', regionId: 'region2' },
            { lineNumber: 15, content: "  selector: 'app-example',", lineType: 'original', regionId: 'region2' },
            { lineNumber: 16, content: "  standalone: true,", lineType: 'original', regionId: 'region2' },
            { lineNumber: 17, content: "  imports: [CommonModule, FormsModule],", lineType: 'original', regionId: 'region2' },
            { lineNumber: 18, content: "  template: `", lineType: 'original', regionId: 'region2' },
            { lineNumber: 19, content: "    <div class=\"container\">", lineType: 'original', regionId: 'region2' },
            { lineNumber: 20, content: "      <h1>{{ title }}</h1>", lineType: 'original', regionId: 'region2' },
            { lineNumber: 21, content: "      <p>用户数量: {{ userCount }}</p>", lineType: 'original', regionId: 'region2' },
            { lineNumber: 22, content: "    </div>", lineType: 'original', regionId: 'region2' },
            { lineNumber: 23, content: "  `,", lineType: 'original', regionId: 'region2' },
            { isCollapsed: true, hiddenStart: 24, hiddenEnd: 34, content: "// ··· 11 行被折叠 ···" },
            { lineNumber: 35, content: "  // 展开隐藏内容", lineType: 'original', regionId: 'region3' },
            { lineNumber: 36, content: "  expandContent(): void {", lineType: 'original', regionId: 'region3' },
            { lineNumber: 37, content: "    this.showHidden = !this.showHidden;", lineType: 'original', regionId: 'region3' },
            { lineNumber: 38, content: "    if (this.showHidden) {", lineType: 'original', regionId: 'region3' },
            { lineNumber: 39, content: "      this.loadAdditionalData();", lineType: 'original', regionId: 'region3' },
            { lineNumber: 40, content: "    }", lineType: 'original', regionId: 'region3' },
            { lineNumber: 41, content: "  }", lineType: 'original', regionId: 'region3' },
            { lineNumber: 42, content: "", lineType: 'original', regionId: 'region3' },
            { isCollapsed: true, hiddenStart: 43, hiddenEnd: 54, content: "// ··· 12 行被折叠 ···" },
            { lineNumber: 55, content: "  // 工具方法", lineType: 'original', regionId: 'region4' },
            { lineNumber: 56, content: "  private formatDate(date: Date): string {", lineType: 'original', regionId: 'region4' },
            { lineNumber: 57, content: "    return date.toLocaleDateString('zh-CN');", lineType: 'original', regionId: 'region4' },
            { lineNumber: 58, content: "  }", lineType: 'original', regionId: 'region4' },
            { lineNumber: 59, content: "", lineType: 'original', regionId: 'region4' },
            { lineNumber: 60, content: "  private calculateAge(birthDate: Date): number {", lineType: 'original', regionId: 'region4' },
            { lineNumber: 61, content: "    const today = new Date();", lineType: 'original', regionId: 'region4' },
            { lineNumber: 62, content: "    const age = today.getFullYear() - birthDate.getFullYear();", lineType: 'original', regionId: 'region4' },
            { lineNumber: 63, content: "    const monthDiff = today.getMonth() - birthDate.getMonth();", lineType: 'original', regionId: 'region4' },
            { lineNumber: 64, content: "    if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {", lineType: 'original', regionId: 'region4' },
            { lineNumber: 65, content: "      return age - 1;", lineType: 'original', regionId: 'region4' },
            { lineNumber: 66, content: "    }", lineType: 'original', regionId: 'region4' },
            { lineNumber: 67, content: "    return age;", lineType: 'original', regionId: 'region4' },
            { isCollapsed: true, hiddenStart: 68, hiddenEnd: 72, content: "// ··· 5 行被折叠 ···" }
        ];

        let currentLines = [...mockCodeLines];

        // 语法高亮处理函数
        function highlightCode(code, language = 'typescript') {
            try {
                if (Prism.languages[language]) {
                    return Prism.highlight(code, Prism.languages[language], language);
                } else {
                    // 如果语言不支持，返回HTML转义的代码
                    return escapeHtml(code);
                }
            } catch (error) {
                console.warn('语法高亮失败:', error);
                return escapeHtml(code);
            }
        }

        // HTML转义函数
        function escapeHtml(text) {
            const div = document.createElement('div');
            div.textContent = text;
            return div.innerHTML;
        }

        // 渲染代码显示
        function renderCodeDisplay() {
            const container = document.getElementById('code-display');
            container.innerHTML = '';

            currentLines.forEach((line, index) => {
                const lineContainer = document.createElement('div');
                lineContainer.className = 'line-container';

                if (line.isCollapsed) {
                    // 折叠占位符行
                    lineContainer.innerHTML = `
                        <div class="collapsed-line">
                            <span class="line-number-range">${line.hiddenStart}-${line.hiddenEnd}</span>
                            <div class="collapsed-content">
                                <span class="collapsed-text">${line.content}</span>
                                <div class="expand-actions">
                                    <button class="expand-btn" onclick="expandRegion(${line.hiddenStart}, ${line.hiddenEnd})">
                                        <span class="expand-icon">▼</span>
                                        展开 ${line.hiddenEnd - line.hiddenStart + 1} 行
                                    </button>
                                </div>
                            </div>
                        </div>
                    `;
                } else {
                    // 普通代码行
                    const backgroundColor = line.lineType === 'original' && line.regionId ? 
                        regionBackgrounds[line.regionId] : 'transparent';
                    const lineTypeClass = line.lineType === 'original' ? 'original-visible' : 'manually-expanded';
                    
                    // 应用语法高亮
                    const highlightedContent = highlightCode(line.content, 'typescript');

                    lineContainer.innerHTML = `
                        <div class="code-line ${lineTypeClass}" style="background-color: ${backgroundColor};">
                            <span class="line-number">${line.lineNumber}</span>
                            <pre class="line-content">${highlightedContent}</pre>
                        </div>
                    `;
                }

                container.appendChild(lineContainer);
            });
        }

        // 展开指定区域
        function expandRegion(startLine, endLine) {
            // 生成被展开的行数据
            const expandedLines = [];
            for (let i = startLine; i <= endLine; i++) {
                expandedLines.push({
                    lineNumber: i,
                    content: `  // 这是第 ${i} 行的示例代码内容`,
                    lineType: 'expanded'
                });
            }

            // 找到对应的折叠项并替换
            for (let i = 0; i < currentLines.length; i++) {
                if (currentLines[i].isCollapsed && 
                    currentLines[i].hiddenStart === startLine && 
                    currentLines[i].hiddenEnd === endLine) {
                    currentLines.splice(i, 1, ...expandedLines);
                    break;
                }
            }

            renderCodeDisplay();
        }

        // 展开所有隐藏行
        function expandAll() {
            const newLines = [];
            
            currentLines.forEach(line => {
                if (line.isCollapsed) {
                    // 替换折叠行为展开的行
                    for (let i = line.hiddenStart; i <= line.hiddenEnd; i++) {
                        newLines.push({
                            lineNumber: i,
                            content: `  // 这是第 ${i} 行的示例代码内容`,
                            lineType: 'expanded'
                        });
                    }
                } else {
                    newLines.push(line);
                }
            });

            currentLines = newLines;
            renderCodeDisplay();
        }

        // 重置显示
        function collapseAll() {
            currentLines = [...mockCodeLines];
            renderCodeDisplay();
        }

        // 重新加载数据
        function reloadData() {
            currentLines = [...mockCodeLines];
            renderCodeDisplay();
            console.log('数据已重新加载');
        }

        // 页面加载完成后初始化
        document.addEventListener('DOMContentLoaded', function() {
            // 等待 Prism.js 加载完成
            setTimeout(() => {
                renderCodeDisplay();
            }, 100);
        });
    </script>
</body>
</html> 